"""
Copyright (c) 2008, Luke Freeman
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

	* Redistributions of source code must retain the above copyright notice, this 
	  list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright notice, this 
	  list of conditions and the following disclaimer in the documentation and/or 
	  other materials provided with the distribution.
	* Neither the name of Flag-Up nor the names of its contributors may 
	  be used to endorse or promote products derived from this software without specific 
	  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
"""

import pygtk
import gtk, gtk.glade

from config.account_manager import *
from config.configuration import *

from ui.status_icon import *
from ui.glade.account_dialog import *
from ui.util import *


# TODO defer saving to the OK button. currently saves at multiple points
# TODO edit button functionality

class PreferencesDialog():

	__PREF_GLADE_FILE = 'ui/glade/preferences_dialog.glade'
	__config = Configuration()
	__acct_mgr = AccountManager()          # the account manager

	def __init__(self, status_icon):    
		self.create_dialog()
		self.status_icon = status_icon


	def create_dialog(self):
		self.widgets = gtk.glade.XML(PreferencesDialog.__PREF_GLADE_FILE)
		self.widgets.signal_autoconnect(self)         # connect the signals defined in the glade file

		# get widget references
		self.window = self.widgets.get_widget('dialog_preferences')      
		self.spin_check_interval = self.widgets.get_widget('spin_check_interval')
		self.check_flash_icon = self.widgets.get_widget('check_flash_icon')
		self.radio_indef_flash = self.widgets.get_widget('radio_indef_flash')
		self.radio_fixed_flash = self.widgets.get_widget('radio_fixed_flash')
		self.spin_flash_interval = self.widgets.get_widget('spin_flash_interval')
		self.lbl_flash_suffix = self.widgets.get_widget('lbl_flash_suffix')    
		self.tree_accounts = self.widgets.get_widget("tree_accounts")


		# define model for accounts tree view 
		self.account_list = gtk.ListStore (gtk.gdk.Pixbuf, bool, str, str)
		self.tree_accounts.set_model(self.account_list)

		cell_renderer_text = gtk.CellRendererText()
		cell_renderer_pixbuf = gtk.CellRendererPixbuf()
		cell_renderer_toggle = gtk.CellRendererToggle()
		cell_renderer_toggle.connect('toggled', self.on_tree_accounts_column_toggled, self.account_list)

		# create the mail account treeview columns
		column = Util.new_treeview_column(self.tree_accounts, cell_renderer_pixbuf, "")
		column.set_min_width(22)
		self.tree_accounts.append_column(column)

		column = Util.new_treeview_column(self.tree_accounts, cell_renderer_toggle, "")
		column.set_min_width(22)
		self.tree_accounts.append_column(column)

		column = Util.new_treeview_column(self.tree_accounts, cell_renderer_text, "Name")
		column.set_min_width(250)
		self.tree_accounts.append_column(column)

		column = Util.new_treeview_column(self.tree_accounts, cell_renderer_text, "Type")
		self.tree_accounts.append_column(column)                


		# load all the currently configured accounts
		for account in self.__acct_mgr.accounts.values():
			snap_in = self.__config.snapin_by_type_description(account.mail_type)
			pixbuf = snap_in.get_icon(snap_in.type)
			self.account_list.append([pixbuf, account.enabled, account.name, account.mail_type])


		# set preferences dialog icon
		pixbuf = self.window.render_icon(gtk.STOCK_PREFERENCES, gtk.ICON_SIZE_MENU)
		self.window.set_icon(pixbuf)

		# set-up dialog to reflect current options
		interval = self.__config.get_value("/check_interval")
		self.spin_check_interval.set_value(interval)

		do_flash = self.__config.get_value("/flash/do")
		self.check_flash_icon.set_active(do_flash)

		fixed = self.__config.get_value("/flash/fixed")    
		self.radio_fixed_flash.set_active(fixed)
		self.radio_indef_flash.set_active(not fixed)

		fixed_interval = self.__config.get_value("/flash/fixed_interval")    
		self.spin_flash_interval.set_value(fixed_interval)


	# re-create the window for each new view but ensure that display is restricted to a single window
	def show(self):
		if self.window.get_property('visible') == False:
			self.create_dialog()
			self.window.show()
		else:
			self.window.get_window().raise_()


	# event handlers ----
	# account maintenance buttons
	def on_btn_add_account_clicked(self, widget):
		result, new_account = AccountDialog(self.window, None).show()

		if (result == gtk.RESPONSE_OK):
			# configure the account information
			self.__acct_mgr.create_or_update_account(new_account)

			# show the entry in the list
			snap_in = self.__config.snapin_by_type_description(new_account.mail_type)
			pixbuf = snap_in.get_icon(snap_in.type)			
			self.account_list.append([pixbuf, new_account.enabled, new_account.name, new_account.mail_type])    



	def show_tree_selection_warning(self, mode):
		if (self.tree_accounts.get_selection().count_selected_rows() == 0):
			message = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, 
				"No Account Selected")
			message.format_secondary_text("Please select the acount you wish to %s and try again" % mode)
			message.run()
			message.destroy()

			return True

		else:
			return False



	def on_btn_edit_account_clicked(self, widget):
		stop_edit = self.show_tree_selection_warning("edit")
		result, edit_account = AccountDialog(self.window, account).show()


	def on_btn_del_account_clicked(self, widget):
		stop_edit = self.show_tree_selection_warning("remove")
		if not stop_edit:
			model, citer = self.tree_accounts.get_selection().get_selected()
			if citer:
				name = self.account_list.get_value(citer, 2)
				model.remove(citer)
				self.__acct_mgr.delete_account(name)



	# dialog buttons
	def on_btn_close_clicked(self, widget):
		self.window.hide_on_delete()


	def on_btn_ok_clicked(self, widget):
		# save configuration
		check_interval = self.spin_check_interval.get_value_as_int()
		self.__config.set_value("/check_interval", check_interval)

		do_flash = self.check_flash_icon.get_active()
		self.__config.set_value("/flash/do", do_flash)

		fixed = self.radio_fixed_flash.get_active()
		self.__config.set_value("/flash/fixed", fixed)

		fixed_interval = self.spin_flash_interval.get_value_as_int()
		self.__config.set_value("/flash/fixed_interval", fixed_interval)

		if (not fixed):
			self.status_icon.blink_for_duration(-1)
		else:
			self.status_icon.blink_for_duration(0)


		self.__config.set_value("/is_configured", True)
		self.window.hide_on_delete()



	# treeview handlers
	def on_tree_accounts_column_toggled(self, cell, path, model):
		# Sets the account enabled/disabled property based on the value of the
		# checkbox in the treeview

		iter = model.get_iter((int(path),))
		name = model.get_value(iter, 1)
		enabled = model.get_value(iter, 0)
		enabled = not enabled

		model.set(iter, 0, enabled)

		account = self.__acct_mgr.get_account_from_name(name)
		account.enabled = enabled
		self.__acct_mgr.create_or_update_account(account)




	def on_check_flash_icon_toggled(self, widget):
		self.radio_indef_flash.set_sensitive(widget.get_active())
		self.radio_fixed_flash.set_sensitive(widget.get_active())

		if self.radio_fixed_flash.get_active():
			self.spin_flash_interval.set_sensitive(widget.get_active())
			self.lbl_flash_suffix.set_sensitive(widget.get_active())


	def on_radio_fixed_flash_toggled(self, widget):   
		self.spin_flash_interval.set_sensitive(widget.get_active())
		self.lbl_flash_suffix.set_sensitive(widget.get_active())


